package com.mhkj.execute.plan.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.CriteriaBuilder.In;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.mhkj.base.busiType.service.BusinessTypeService;
import com.mhkj.base.calender.service.WorkCalenderService;
import com.mhkj.base.fruitType.entity.FruitType;
import com.mhkj.base.fruitType.service.FruitTypeService;
import com.mhkj.base.functionOffice.entity.FunctionOffice;
import com.mhkj.base.itemInfo.item.entity.Item;
import com.mhkj.base.itemInfo.item.service.ItemService;
import com.mhkj.common.util.ItemHelper;
import com.mhkj.execute.plan.repository.PlanNodeExecutionRepository;
import com.mhkj.execute.plan.service.PlanNodeExecutionService;
import com.mhkj.revise.plan.entity.PlanNode;
import com.mhkj.revise.plan.service.PlanService;
import com.mics.core.common.componet.Pagination;
import com.mics.core.common.util.UserHelper;
import com.mics.core.system.base.service.impl.BaseServiceImpl;
import com.mics.core.system.organizational.bean.Employee;
import com.mics.core.system.organizational.bean.Office;
import com.mics.core.system.organizational.bean.Post;
import com.mics.core.system.organizational.service.OrgService;
import com.mics.core.system.organizational.service.PermissionService;
import com.mics.core.system.rbac.entity.Dictionary;
import com.mics.core.system.rbac.service.DictionaryService;

/**
 * 计划节点名称
 * 
 * @author mics
 * @date 2018年7月6日
 * @version 1.0
 */
@Service
public class PlanNodeExecutionServiceImpl extends BaseServiceImpl<PlanNode> implements PlanNodeExecutionService {
	@Resource
	private PlanNodeExecutionRepository planNodeExecutionRepository;
	@Resource
	private WorkCalenderService calenderService;
	@Resource
	private BusinessTypeService businessTypeService;
	@Resource
	private OrgService orgService;
	@Resource
	private PermissionService permissionService;
	@Resource
	private DictionaryService dictionaryService;
	@Resource
	private ItemService itemService;
	@Resource
	private ItemHelper itemHelper;
	@Resource
	private PlanService planService;
	@Resource
	private FruitTypeService fruitTypeService;

	@Resource
	public void setPlanNodeExecutionRepository(PlanNodeExecutionRepository planNodeExecutionRepository) {
		super.setBaseRepository(planNodeExecutionRepository);
	}

	/**
	 * 根据节点名称和月份查询月度计划
	 * 
	 * @author wk
	 * @date 2018年8月14日
	 * @version 1.0
	 */
	public Pagination<PlanNode> monthlyPlanListByPage(String nodeName, String startDate, String endDate, String state,
			Long itemId,int pageIndex, int pageSize) {

		Specification<PlanNode> spec = new Specification<PlanNode>() {
			private static final long serialVersionUID = -786003485941679959L;

			@Override
			public Predicate toPredicate(Root<PlanNode> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> lstPredicates = new ArrayList<Predicate>();
				Join<Object, Object> plan = root.join("plan", JoinType.INNER);
				Join<Object, Object> planType = plan.join("planType", JoinType.INNER);
				if (!StringUtils.isEmpty(nodeName)) {
					Predicate p1 = criteriaBuilder.like(root.get("nodeName").as(String.class), "%" + nodeName + "%");
					lstPredicates.add(p1);
				}
				if (!StringUtils.isEmpty(startDate)) {
					try {
						Date endDate1 = new SimpleDateFormat("yyyy-MM-dd").parse(endDate);
						Date beginDate = new SimpleDateFormat("yyyy-MM-dd").parse(startDate);
						Predicate p4 = criteriaBuilder.lessThanOrEqualTo(root.get("beginDate"), endDate1);
						Predicate p5 = criteriaBuilder.greaterThanOrEqualTo(root.get("endDate"), beginDate);
						lstPredicates.add(p4);
						lstPredicates.add(p5);
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
				String[] states = state.split(",");

				if (!StringUtils.isEmpty(state)) {
					In<Object> in = criteriaBuilder.in(root.get("state").as(String.class));
					for (String state : states) {
						in.value(state);
					}
					lstPredicates.add(in);
				}
				Join<Object, Object> item = plan.join("item",JoinType.LEFT);
                if(itemHelper.getCurrentUserItems().size() > 0 ){
					Predicate p3=criteriaBuilder.and(item.in(itemHelper.getCurrentUserItems()));
					Predicate p4=criteriaBuilder.and(item.isNull());
		            lstPredicates.add(criteriaBuilder.or(p3,p4));
                }else{
					Predicate p3=criteriaBuilder.and(item.isNull());
		            lstPredicates.add(p3);
                }
				if (!StringUtils.isEmpty(itemId)) {
					lstPredicates
							.add(criteriaBuilder.equal(item.get("id").as(Long.class), itemId));
				}
				Predicate p3 = criteriaBuilder.equal(plan.get("state").as(long.class), "2");
				lstPredicates.add(p3);
				Dictionary dictionary = dictionaryService.getByValue("专项计划");
				Dictionary dictionary2 = dictionaryService.getByValue("职能计划");
				Predicate p6 = criteriaBuilder.equal(planType.get("id").as(long.class), dictionary.getId());
				Predicate p7 = criteriaBuilder.equal(planType.get("id").as(long.class), dictionary2.getId());
				lstPredicates.add(criteriaBuilder.or(p6,p7));
				
				
				List<Post> list =UserHelper.getCurrentEmployee().getRoleList();

				//获取岗位信息，对比当前登录人的岗位
					if (list != null && list.size() > 0) {
						In<Object> in = criteriaBuilder.in(root.get("postId"));
						for (Post post : list) {
							in.value(post.getId());
						}
						lstPredicates.add(in);
					}
/*	            lstPredicates.add(criteriaBuilder.equal(root.get("postId").as(String.class), UserHelper.getCurrentEmployee().getRoleList().get(0).getId()));
*/				Predicate[] arrayPredicates = new Predicate[lstPredicates.size()];
				return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
			}
		};
		Page<PlanNode> pageT = planNodeExecutionRepository.findAll(spec,
				PageRequest.of(pageIndex, pageSize, Sort.Direction.ASC, "id"));
		Pagination<PlanNode> pagination = new Pagination<PlanNode>();
		pagination.setTotal(planNodeExecutionRepository.count(spec));
		List<PlanNode> plans = pageT.getContent();
		List<FruitType> fruitTypeList = fruitTypeService.findAll();
		for (PlanNode planNode2 : plans) {
			List<Employee> postInfo = orgService
					.getEmployeeByPost(planNode2.getPostId());/*
																 * Gson gson = new GsonBuilder().create(); Employee post
																 * = gson.fromJson(postInfo, Employee.class);
																 */
			if (postInfo.size() > 0) {
				planNode2.setPostName(postInfo.get(0).getName());
			}
			for (FruitType fruitType : fruitTypeList) {
				if (planNode2.getNodeTempleteDataId() != null) {
					if (fruitType.getNodeResult().equals(planNode2.getNodeTempleteDataId())) {
						planNode2.setFruitType("1");
					}
				}

			}

		}
		pagination.setData(plans);
		return pagination;
	}

	/**
	 * 受影响的节点
	 * 
	 * @param planNode
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	@Override
	public Pagination<PlanNode> affectedListByPage(PlanNode planNode, int pageIndex, int pageSize) {
		Specification<PlanNode> spec = new Specification<PlanNode>() {
			private static final long serialVersionUID = -786003485941679959L;

			@Override
			public Predicate toPredicate(Root<PlanNode> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> lstPredicates = new ArrayList<Predicate>();
				if (!StringUtils.isEmpty(planNode.getNodeName())) {
					Predicate p1 = criteriaBuilder.like(root.get("deadlineDesc").as(String.class),
							"%" + planNode.getNodeName() + "%");
					lstPredicates.add(p1);
				}
				if (!StringUtils.isEmpty(planNode.getPlan())) {
					Join<Object, Object> plan = root.join("plan", JoinType.LEFT);
					Predicate p2 = criteriaBuilder.equal(plan.get("id"), planNode.getPlan().getId());
					lstPredicates.add(p2);
				}
				Predicate[] arrayPredicates = new Predicate[lstPredicates.size()];
				return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
			}
		};
		Page<PlanNode> pageT = planNodeExecutionRepository.findAll(spec,
				PageRequest.of(pageIndex, pageSize, Sort.Direction.ASC, "id"));
		Pagination<PlanNode> pagination = new Pagination<PlanNode>();
		pagination.setTotal(planNodeExecutionRepository.count(spec));
		List<PlanNode> plans = pageT.getContent();
		for (PlanNode planNode2 : plans) {
			Office cOffice = orgService.officeInfo(planNode2.getOfficeId());
			planNode2.setOfficeName(cOffice.getName());
			List<Employee> postInfo = orgService
					.getEmployeeByPost(planNode2.getPostId());/*
																 * Gson gson = new GsonBuilder().create(); Employee post
																 * = gson.fromJson(postInfo, Employee.class);
																 */
			if (postInfo.size() > 0) {
				planNode2.setPostName(postInfo.get(0).getName());
			}

		}
		pagination.setData(plans);
		return pagination;
	}

	/**
	 * 其他节点
	 * 
	 * @param planNode
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	/*
	 * public List<PlanNode> listByPage(PlanNode planNode,String startDate,String
	 * endDate, int pageIndex,int pageSize){ long
	 * planType=planNode.getNodeProperty().getId();
	 * 
	 * List<PlanNode> list= planNodeExecutionRepository.listByPage(planType);
	 * for(PlanNode planNode2 : list){ List<Employee> postInfo =
	 * orgService.getEmployeeByPost(planNode2.getPostId()); Gson gson = new
	 * GsonBuilder().create(); Employee post = gson.fromJson(postInfo,
	 * Employee.class); if(postInfo.size()>0) {
	 * planNode2.setPostName(postInfo.get(0).getName()); } } return list; }
	 */

	/**
	 * 其他节点
	 * 
	 * @param planNode
	 * @param pageIndex
	 * @param pageSize
	 * @return
	 */
	public Pagination<PlanNode> listByPage(PlanNode planNode, String startDate, String endDate,Long itemId, int pageIndex,
			int pageSize) {

		Specification<PlanNode> spec = new Specification<PlanNode>() {
			private static final long serialVersionUID = -786003485941679959L;

			@Override
			public Predicate toPredicate(Root<PlanNode> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> lstPredicates = new ArrayList<Predicate>();

				Join<Object, Object> plan = root.join("plan", JoinType.INNER);
				Join<Object, Object> planType = plan.join("planType", JoinType.INNER);

				if (!StringUtils.isEmpty(planNode.getNodeProperty().getId())) {
					Predicate p2 = criteriaBuilder.equal(planType.get("id"), planNode.getNodeProperty().getId());
					lstPredicates.add(p2);
				}
				if (!StringUtils.isEmpty(planNode.getNodeName())) {
					Predicate p1 = criteriaBuilder.like(root.get("nodeName").as(String.class),
							"%" + planNode.getNodeName() + "%");
					lstPredicates.add(p1);
				}
				if (!StringUtils.isEmpty(startDate)) {
					try {
						Date endDate1 = new SimpleDateFormat("yyyy-MM-dd").parse(endDate);
						Date beginDate = new SimpleDateFormat("yyyy-MM-dd").parse(startDate);
						Predicate p4 = criteriaBuilder.lessThanOrEqualTo(root.get("beginDate"), endDate1);
						Predicate p5 = criteriaBuilder.greaterThanOrEqualTo(root.get("endDate"), beginDate);
						lstPredicates.add(p4);
						lstPredicates.add(p5);
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}

				Join<Object, Object> item = plan.join("item",JoinType.LEFT);
				//判断项目权限和职能权限
                List<Item> items = itemHelper.getCurrentUserItems();
                List<FunctionOffice> functionOffices = itemHelper.getCurrentUserFunctionOffices();
                Predicate pitem = null;
                Predicate pfunction = null;
                if(itemHelper.getCurrentUserItems().size() > 0 ){
                	pitem=plan.get("item").in(items);
                }else{
                	pitem=plan.get("item").isNull();
                }
                if(itemHelper.getCurrentUserFunctionOffices().size() > 0 ){
                	 pfunction=plan.get("functionOffice").in(functionOffices);
                }else{
                	  pfunction=plan.get("functionOffice").isNull();
                }
		       lstPredicates.add(criteriaBuilder.or(pitem, pfunction));
                
				if (!StringUtils.isEmpty(itemId)) {
					lstPredicates
							.add(criteriaBuilder.equal(item.get("id").as(Long.class), itemId));
				}
				Predicate p3 = criteriaBuilder.equal(plan.get("state").as(long.class), "2");
				lstPredicates.add(p3);/*
	            lstPredicates.add(criteriaBuilder.equal(root.get("postId").as(String.class), UserHelper.getCurrentEmployee().getRoleList().get(0).getId()));*/
				Predicate[] arrayPredicates = new Predicate[lstPredicates.size()];
				return criteriaBuilder.and(lstPredicates.toArray(arrayPredicates));
			}
		};
		Page<PlanNode> pageT = planNodeExecutionRepository.findAll(spec,
				PageRequest.of(pageIndex, pageSize, Sort.Direction.ASC, "id"));
		Pagination<PlanNode> pagination = new Pagination<PlanNode>();
		pagination.setTotal(planNodeExecutionRepository.count(spec));
		List<PlanNode> plans = pageT.getContent();

		for (PlanNode planNode2 : plans) {
			List<Employee> postInfo = orgService
					.getEmployeeByPost(planNode2.getPostId());/*
																 * Gson gson = new GsonBuilder().create(); Employee post
																 * = gson.fromJson(postInfo, Employee.class);
																 */
			if (postInfo.size() > 0) {
				planNode2.setPostName(postInfo.get(0).getName());
			}
		}
		pagination.setData(plans);
		return pagination;
	}

	/**
	 * 月度计划统计
	 */
	public Map<String, Object> workbenchCount(String startDate, String endDate) {
		List<Item> itemList= itemHelper.getCurrentUserItems();
		List<String> itemId = new ArrayList<>();
		for (Item item:itemList) {
				itemId.add(item.getId()+"");
		}
		if(itemId.isEmpty()) {
			itemId.add(0+"");
		}
		List<Post> list= UserHelper.getCurrentEmployee().getRoleList();
		List<String> postId = new ArrayList<>();
		for (Post post : list) {
			postId.add(post.getId());
		
		}
		return planNodeExecutionRepository.workbenchCount(startDate, endDate,itemId,postId);

	}

	@Override
	public List<Map<String, Object>> dataPrintInfo(Long planNodeId) {
		// TODO Auto-generated method stub
		return planNodeExecutionRepository.dataPrintInfo(planNodeId);
	}


}
